home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / FPSE_src / hw.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  22KB  |  814 lines

  1. /*
  2.     Hardware addressing
  3.     ===================
  4.  
  5.     Written by LDChen
  6.     Modified by LDChen
  7. */
  8.  
  9. #include "fpse.h"
  10.  
  11. #ifdef MSB_FIRST
  12. #define   HW8(a)  hwarea[4*((a)/4)+3-(a)%4]
  13. #define   HW16(a) (*(UINT16*)&hwarea[4*((a)/4)+2-(a)%4])
  14. #define   HW32(a) (*(UINT32*)&hwarea[a])
  15. #else
  16. #define   HW8(a)  hwarea[a]
  17. #define   HW16(a) (*(UINT16*)&hwarea[a])
  18. #define   HW32(a) (*(UINT32*)&hwarea[a])
  19. #endif
  20.  
  21. #define NOPRINTPC   1
  22.  
  23. typedef struct {
  24.      UINT32 addr;
  25.      char  *name;
  26. } NAM;
  27.  
  28. /*
  29.      1f801000
  30.      1f801004
  31.      1f801008
  32.      1f80100c
  33.      1f801010
  34.      1f80101c
  35.      1f802041  ???
  36. */
  37. static NAM hwnames[] = {
  38.      {0x1f801014,"spu_delay"},
  39.      {0x1f801018,"dv5_delay"},
  40.      {0x1f801020,"com_delay"},
  41.  
  42.      {0x1f801040,"sio0_data"},
  43.      {0x1f801044,"sio0_status"},
  44.         {0x1f801048,"sio0_mode"},
  45.      {0x1f80104a,"sio0_control"},
  46.      {0x1f80104e,"sio0_baud"},
  47.  
  48.      {0x1f801050,"sio1_data"},
  49.      {0x1f801054,"sio1_status"},
  50.         {0x1F801058,"sio1_mode"},
  51.      {0x1f80105a,"sio1_control"},
  52.      {0x1f80105e,"sio1_baud"},
  53.  
  54.      {0x1f801060,"ram_size"},
  55.  
  56.      {0x1f801070,"int_reg"},
  57.      {0x1f801074,"int_mask"},
  58.      
  59.      {0x1f801080,"mdec_dma0_madr"},
  60.      {0x1f801084,"mdec_dma0_bcr"},
  61.      {0x1f801088,"mdec_dma0_chcr"},
  62.      
  63.      {0x1f801090,"mdec_dma1_madr"},
  64.      {0x1f801094,"mdec_dma1_bcr"},
  65.      {0x1f801098,"mdec_dma1_chcr"},
  66.      
  67.      {0x1f8010a0,"gpu_dma_madr"},
  68.      {0x1f8010a4,"gpu_dma_bcr"},
  69.      {0x1f8010a8,"gpu_dma_chcr"},
  70.      
  71.      {0x1f8010b0,"cd_dma_madr"},
  72.      {0x1f8010b4,"cd_dma_bcr"},
  73.      {0x1f8010b8,"cd_dma_chcr"},
  74.      
  75.      {0x1f8010c0,"spu_dma_madr"},
  76.      {0x1f8010c4,"spu_dma_bcr"},
  77.      {0x1f8010c8,"spu_dma_chcr"},
  78.      
  79.      {0x1f8010d0,"dma5_madr"},
  80.      {0x1f8010d4,"dma5_bcr"},
  81.      {0x1f8010d8,"dma5_chcr"},
  82.      
  83.      {0x1f8010e0,"dma6_madr"},
  84.      {0x1f8010e4,"dma6_bcr"},
  85.      {0x1f8010e8,"dma6_chcr"},
  86.      
  87.      {0x1f8010f0,"dma_pcr"},
  88.      {0x1f8010f4,"dma_icr"},
  89.  
  90.      {0x1f801100,"t0_count"},
  91.      {0x1f801104,"t0_mode"},
  92.      {0x1f801108,"t0_target"},
  93.  
  94.      {0x1f801110,"t1_count"},
  95.      {0x1f801114,"t1_mode"},
  96.      {0x1f801118,"t1_target"},
  97.  
  98.      {0x1f801120,"t2_count"},
  99.      {0x1f801124,"t2_mode"},
  100.      {0x1f801128,"t2_target"},
  101.  
  102.      {0x1f801800,"cdrom_reg0"},
  103.      {0x1f801801,"cdrom_reg1"},
  104.      {0x1f801802,"cdrom_reg2"},
  105.      {0x1f801803,"cdrom_reg3"},
  106.  
  107.      {0x1f801810,"gpu_reg0"},
  108.      {0x1f801814,"gpu_reg1"},
  109.  
  110.      {0x1f801820,"mdec_reg0"},
  111.      {0x1f801824,"mdec_reg1"},
  112.  
  113.      {0x1f801d80,"spu_mvol_l"},
  114.      {0x1f801d82,"spu_mvol_r"},
  115.      {0x1f801d84,"spu_reverb_l"},
  116.      {0x1f801d86,"spu_reverb_r"},
  117.      {0x1f801d88,"spu_key_on_1"},
  118.      {0x1f801d8a,"spu_key_on_2"},
  119.      {0x1f801d8c,"spu_key_off_1"},
  120.      {0x1f801d8e,"spu_key_off_2"},
  121.      {0x1f801d90,"spu_key_modefm_1"},
  122.      {0x1f801d92,"spu_key_modefm_2"},
  123.      {0x1f801d94,"spu_key_modenoise_2"},
  124.      {0x1f801d96,"spu_key_modenoise_2"},
  125.      {0x1f801d98,"spu_key_modereverb_1"},
  126.      {0x1f801d9a,"spu_key_modereverb_2"},
  127.      {0x1f801d9c,"spu_key_channelactive_1"},
  128.      {0x1f801d9e,"spu_key_channelactive_2"},
  129.  
  130.      {0x1f801da6,"spu_sbaddr"},
  131.      {0x1f801da8,"spu_data"},
  132.      {0x1f801daa,"spu_reg0"},
  133.      {0x1f801dac,"spu_reg1"},
  134.      {0x1f801dae,"spu_status"},
  135.  
  136.      {0x1f801db0,"spu_cdvol_l"},
  137.      {0x1f801db2,"spu_cdvol_r"},
  138.      {0x1f801db4,"spu_extvol_l"},
  139.      {0x1f801db6,"spu_extvol_r"},
  140.  
  141.      {0x1f801dc0,"spu_reverbconfig"},
  142.      {0x1f801dfc,"spu_factor_l"},
  143.      {0x1f801dfe,"spu_factor_r"},
  144.  
  145.      {0x1f802030,"int_2000"},
  146.      {0x1f802040,"dip_switches"},
  147.  
  148.      /* extension */
  149.      {0x1f000000,"parrom_status"},
  150.      {0x1f000001,"parrom_type"},
  151.      {0x1f005555,"parrom_reg0"},
  152.      {0x1f002aaa,"parrom_reg1"},
  153.      {0x1f060000,"par_in"}, /* byte */
  154.      {0x1f060008,"par_out"}, /* byte */
  155.      {0x1f020010,"par_status"}, /* bit 0: 1= busy */
  156.      {0x1f020018,"par_switch"}, /* bit 0: 1= on */
  157.  
  158.      {0,""}
  159. };
  160.  
  161. static char *sregname[] = {
  162.      "vol_l","vol_r","freq","sbadr","ar","adsr2","adsrvol","repeat"
  163. };
  164.  
  165. char* hwname(unsigned long addr)
  166. {
  167.      NAM *p;
  168.      static char buf[16];
  169.      for(p=hwnames; p->addr && p->addr!=addr; p++) ;
  170.      if (p->addr) return p->name;
  171.      if (addr>=0x1f801c00 && addr<0x1f801c00+16*24) {
  172.           sprintf(buf,"voice%d_%s",(int)((addr-0x1f801c00)/16),sregname[(addr&15)/2]);
  173.      } else  sprintf(buf,"%08x",(int)addr);
  174.      return buf;
  175. }
  176.  
  177. #define   spu_reg0  HW16(0x1daa)
  178. #define   t0_count  HW16(0x1100)
  179. #define   t0_mode   HW32(0x1104)
  180. #define   t0_target HW16(0x1108)
  181. #define   t1_count  HW16(0x1110)
  182. #define   t1_mode   HW32(0x1114)
  183. #define   t1_target HW16(0x1118)
  184. #define   t2_count  HW16(0x1120)
  185. #define   t2_mode   HW32(0x1124)
  186. #define   t2_target HW16(0x1128)
  187. #define   int_reg   HW16(0x1070)
  188. #define   int_mask  HW16(0x1074)
  189. #define   dma_pcr   HW32(0x10f0)
  190. #define   dma_icr   HW32(0x10f4)
  191.  
  192. UINT8 hwarea[0x8000];
  193.  
  194. /*
  195.      counter mode
  196.  
  197.      base = 0x48
  198.      0x10 Š„‚肱‚Ý‹–‰Â?
  199.      0x01 ƒQ[ƒgðŒ—LŒø
  200.      0x100     0=clock/8 1=clock
  201. */
  202.  
  203. #define INTERRUPT(no) reg |= (1<<no)
  204.  
  205. #define UPPER   0xFFFF
  206.  
  207. static UINT32 base_count;
  208. static UINT32 base_count2;
  209. static UINT32 t0_limit=UPPER;
  210. static UINT32 t1_limit=UPPER;
  211. static UINT32 t2_limit=UPPER;
  212.  
  213. int Irq_Pulse = 0;
  214.  
  215. INT32  VSync_Register = 0;
  216. INT32  Event_Register = 0;
  217. INT32  Event_List[16];
  218. UINT32 Event_Mask[16];
  219.  
  220. int (*EventCallBack[16])();
  221. int (*VSyncCallBack[16])();
  222.  
  223. #define MAINCLOCK   33868800L
  224.  
  225. #define   PER  64
  226.  
  227. #define HSYNC   (MAINCLOCK/15734)
  228. #define VSYNC   (MAINCLOCK/60)
  229. #define ESYNC   13
  230.  
  231. static int treg=0;
  232.  
  233. static int dec1_count=HSYNC;
  234.  
  235. int update_hw(void)
  236. {
  237.     int reg = 0;
  238.     int tmp;
  239.  
  240.     base_count+=PER;
  241.  
  242.     if (base_count>=VSYNC) {
  243.         base_count=0;
  244.  
  245.         PRINTF("VSync\n");
  246.         win_update();
  247.         INTERRUPT(INT_VSync);
  248.     }
  249.  
  250.     tmp = t0_count + ((t0_mode & 0x100)?PER:PER/8);
  251.     if (tmp>=t0_limit && t0_count<t0_limit) {
  252.         tmp = 0;
  253. // printf("t0 == limit\n");
  254.         if (t0_mode & 0x50) INTERRUPT(INT_CNT0);
  255.     }
  256.     t0_count=tmp;
  257.  
  258.     if ((t1_mode & 0x100)==0) {
  259.         tmp = t1_count + PER;
  260.  
  261.         if (tmp>=t1_limit && t1_count<t1_limit) {
  262.             tmp = 0;
  263. // printf("t1 == limit\n");
  264.             if (t1_mode & 0x50) INTERRUPT(INT_CNT1);
  265.         }
  266.         t1_count=tmp;
  267.     } else
  268.     if ((dec1_count-=PER) <= 0) {
  269.         if (++t1_count == t1_limit) {
  270.             t1_count = 0;
  271. // printf("t1 == limit\n");
  272.             if (t1_mode & 0x50) INTERRUPT(INT_CNT1);
  273.         }
  274.         dec1_count = HSYNC;
  275.     }
  276.  
  277.     if ((t2_mode & 1) == 0)
  278.     {
  279.         tmp = t2_count + ((t2_mode & 0x200)?PER/8:PER);
  280.         if (tmp>=t2_limit && t2_count<t2_limit) {
  281.             tmp = 0;
  282. // printf("t2 == limit\n");
  283.             if (t2_mode & 0x50) INTERRUPT(INT_CNT2);
  284.         }
  285.         t2_count=tmp;
  286.     }
  287.  
  288.     if (++base_count2>=ESYNC) {
  289.         base_count2=0;
  290.         if (VSync_Register < 0)
  291.         {
  292.             int v = 1;
  293. //            PRINTF("Entering VSYNC EVENT\n");
  294.             for (tmp=0;tmp<16;tmp++)
  295.             {
  296.                 if ((VSync_Register & v) && --Event_List[tmp] <= 0)
  297.                 {
  298.                     PRINTF("Found %d^ ASync\n",tmp);
  299.                     treg |= v;
  300.                     VSync_Register ^= v;
  301.                     if ( (VSyncCallBack[tmp]) )
  302.                     {
  303.                         if (!VSyncCallBack[tmp]()) treg &= ~v;
  304.                     }
  305.                 }
  306.                 v <<= 1;
  307.             }
  308.             if ((VSync_Register & 0x7FFFFFFF) == 0) 
  309.                 VSync_Register = 0;
  310.         }
  311.     }
  312.  
  313.     if (dma_icr&0x7f000000) { INTERRUPT(INT_DMA); }
  314.  
  315.     if (Event_Register < 0)
  316.     {
  317.         int x,y;
  318.  
  319. //printf("Async event enabled: %08x\n",Event_Register);
  320.             for(x=0;x<16;x++)
  321.             {
  322.                 y = Event_Mask[x];
  323. //printf("Event_List[%d]=%d\n",x,Event_List[x]);
  324.                 if ((Event_Register & y) && Event_List[x] <= 0)
  325.                 {
  326.                     treg |= y;
  327.                     Event_Register &= ~y;
  328.                     if ( (EventCallBack[x]) )
  329.                     {
  330.                         if (!EventCallBack[x]()) treg &= ~y;
  331.                     }
  332.                 }
  333.             }
  334.             if (!(Event_Register & 0x7FFFFFFF))
  335.                 Event_Register = 0;
  336.     }
  337.  
  338.     reg |= Irq_Pulse;
  339.     HW32(0x1070) |= reg;
  340.     Irq_Pulse = tmp = 0;
  341.     if ((HW32(0x1074) & HW32(0x1070)))
  342.         tmp = 1;
  343.  
  344.     HW32(0x1070) |= treg;
  345.     if ( (treg) && (HW32(0x1074) & treg) )
  346.         tmp = 1;
  347.  
  348.     treg=0;
  349.  
  350.     return tmp;
  351. }
  352.  
  353. int update_counter(void)
  354. {
  355.     return update_hw();
  356. }
  357.  
  358. /* OT clear */
  359. void dma6_exec(UINT32 adr,UINT32 bcr,UINT32 chcr)
  360. {
  361.     if (chcr!=0x11000002) {
  362.         PRINTF("dma6 unknown %x\n",(int)chcr);
  363.         return;
  364.     }
  365.  
  366.     if (!bcr) return;
  367.  
  368.     adr &= 0xFFFFFF;
  369.  
  370.     CompileFlush(adr-bcr*4,adr);
  371.  
  372.     while (--bcr) {
  373.         *(UINT32*)&ram[adr & 0x1FFFFF] = SWAP32((adr-4)&0xffffff);
  374.         adr-=4;
  375.     }
  376.  
  377.     *(UINT32*)&ram[adr & 0x1FFFFF] = SWAP32(0xffffff);
  378. }
  379.  
  380. int hw_init(void)
  381. {
  382.     int x;
  383.  
  384. #if AUTOSPEED
  385.     time_t t1;
  386.     UINT32 clk1 = rdtsc();
  387.  
  388.     t1 = clock() + CLOCKS_PER_SEC;
  389.     while (clock() < t1);
  390.     oldcnt = rdtsc();
  391.     cpuspeed = (oldcnt - clk1);
  392.     printf("CPU speed: %d MHz\n",(int)(cpuspeed/1000000));
  393.     vsync = cpuspeed / 60; // -> 550000
  394.     hsync = vsync / 250;
  395. #endif
  396.  
  397.     memset(hwarea,0,0x8000);
  398.  
  399. // Init event masks
  400.     for (x=0;x<16;x++) {
  401.         Event_Mask[x] = 1<<x;
  402.         EventCallBack[x] = NULL;
  403.         VSyncCallBack[x] = NULL;
  404.     }
  405.  
  406. // Start initialization
  407.     mdec_init();
  408.     if (sio_init() != FPSE_OK) return FPSE_ERR;
  409.     cd_initvar();
  410.     if (win_init() != FPSE_OK) return FPSE_ERR;
  411.  
  412.     return FPSE_OK;
  413. }
  414.  
  415. void hw_close(void)
  416. {
  417.     win_term();
  418. }
  419.  
  420. static UINT32 ParReply = 0x57;
  421.  
  422. UINT8 hw_romread(UINT32 adr)
  423. {
  424.     int ret;
  425.  
  426.     switch (adr) {
  427.     case 0x1F020018:
  428.     case 0x1F020010:
  429.         ret = 1; break;
  430.     case 0x1F060000: 
  431.         if (ParReply & 0xF0) ret = ParReply;
  432.         else {
  433.             if (ParReply < 4) ret = extrom[3-ParReply];
  434.                          else ret = 0;
  435.             ParReply++;
  436.         }
  437.         break;
  438.     default:
  439.         if (adr > 0x1F000000 &&
  440.             adr < 0x1F020000) ret = *(UINT32 *)&extrom[adr & 0x1FFFF];
  441.         else ret = 0xFFFFFFFF; // Out of address
  442.         break;
  443.     }
  444.  
  445.     PRINTF("read rom extension %s,%02x\n",hwname(adr),ret);
  446.     return ret;
  447. }
  448.  
  449. void hw_romwrite(UINT32 adr, UINT32 data)
  450. {
  451.     PRINTF("write rom extension %s,%02x\n",hwname(adr),(int)data);
  452.  
  453.     data &= 0xFF;
  454.  
  455.     switch (adr) {
  456.     case 0x1F060008:
  457.         switch (data) {
  458.         case 0x52: ParReply = 0x42; break;
  459.         case 0x57: if (actionreplay) ParReply = 0x58;
  460.                                 else ParReply = 0x55;
  461.                    break;
  462.         case 0x55:
  463.         case 0x58: ParReply = 0; break;
  464.         default: break;
  465.         }
  466.         break;
  467.     }
  468. }
  469.  
  470. UINT8 hw_read8(UINT32 adr)
  471. {
  472.      int ret;
  473.      switch(adr){
  474.      case 0x1f801040: ret = sio_readdata8(&Sio0); break;
  475.      case 0x1f801050: ret = sio_readdata8(&Sio1); break;
  476.      case 0x1f801800: ret = cd0_read(); break;
  477.      case 0x1f801801: ret = cd1_read(); break;
  478.      case 0x1f801802: ret = cd2_read(); break;
  479.      case 0x1f801803: ret = cd3_read(); break;
  480.      default:
  481.           ret = HW8(adr-0x1f800000); break;
  482.      }
  483. #if NOPRINTPC
  484.      printpc();
  485. #endif
  486.      PRINTF("read byte %s,%02x\n",hwname(adr),ret);
  487.      return ret;
  488. }
  489.  
  490. UINT16 hw_read16(UINT32 adr)
  491. {
  492.      int ret;
  493.  
  494.      switch(adr){
  495.      case 0x1f801070:
  496.         if (Event_Register < 0)
  497.         {
  498.             int x,y;
  499.  
  500. //            ret = Event_RootCount;
  501. //            Event_RootCount++;
  502.             for(x=0;x<16;x++)
  503.             {
  504.                 y = Event_Mask[x];
  505.                 if (Event_Register & y)
  506. //                    if (ret >= Event_List[x])
  507.                     if (--Event_List[x] <= 0)
  508.                     {
  509.                         treg |= y;
  510.                         Event_Register &= ~y;
  511.                     }
  512.                 if (!(Event_Register & 0x7FFFFFFF))
  513.                     Event_Register = 0;
  514.             }
  515.         }
  516.         ret= HW16(0x1070)|treg; break;
  517.  
  518. /* SIO0 - Controllers & MemCards */
  519.      case 0x1f801040: ret = sio_readdata16(&Sio0); break;
  520.      case 0x1f801044: ret = Sio0.Status; break;
  521.         case 0x1F801048: ret = Sio0.Mode; break;
  522.      case 0x1f80104a: ret = Sio0.Ctrl.Control16; break;
  523.      case 0x1f80104e: ret = Sio0.Baud; break;
  524. /* SIO1 - Serial port */
  525.      case 0x1f801050: ret = sio_readdata16(&Sio1); break;
  526.      case 0x1f801054: ret = Sio1.Status; break;
  527.         case 0x1F801058: ret = Sio1.Mode; break;
  528.      case 0x1f80105a: ret = Sio1.Ctrl.Control16; break;
  529.      case 0x1f80105e: ret = Sio1.Baud; break;
  530. /*
  531.      case 0x1f801daa:
  532.      case 0x1f801dae:
  533.           return HW16(adr-0x1f800000);
  534. */
  535.      default:
  536.           if (adr>=0x1f801c00 && adr<0x1f801e00)
  537.                ret = SPU_Read(adr);
  538.                 else ret = HW16(adr & 0x7FFF);
  539.                 break;
  540.         }
  541. #if NOPRINTPC
  542.      printpc();
  543. #endif
  544.      PRINTF("read short %s,%04x\n",hwname(adr),ret);
  545.      return ret;
  546. }
  547.  
  548. UINT32 hw_read32(UINT32 adr)
  549. {
  550.      UINT32 ret;
  551.  
  552.      switch(adr) {
  553.      case 0x1f801810: ret = GP0_Read(); break;
  554.      case 0x1f801814: ret = GP1_Read(); break;
  555. /* SIO0 */
  556.      case 0x1f801040: ret = sio_readdata32(&Sio0); break;
  557. /* SIO1 */
  558.      case 0x1f801050: ret = sio_readdata32(&Sio1); break;
  559.  
  560.      case 0x1f801070:
  561.         if (Event_Register < 0)
  562.         {
  563.             int x,y;
  564.  
  565. //            ret = Event_RootCount;
  566. //            Event_RootCount++;
  567. //printf("Async event enabled: %08x\n",Event_Register);
  568.             for(x=0;x<16;x++)
  569.             {
  570. //printf("Event_List[%d]=%d\n",x,Event_List[x]);
  571.                 y = Event_Mask[x];
  572.                 if (Event_Register & y)
  573. //                    if (ret >= Event_List[x])
  574.                     if (--Event_List[x] <= 0)
  575.                     {
  576.                         treg |= y;
  577.                         Event_Register &= ~y;
  578.                     }
  579.                 if (!(Event_Register & 0x7FFFFFFF))
  580.                     Event_Register = 0;
  581.             }
  582.         }
  583.         ret= HW32(0x1070)|treg; break;
  584.      case 0x1f801820: ret = mdec0_read(); break;
  585.      case 0x1f801824: ret = mdec1_read(); break;
  586. #if 0
  587.      case 0x1f801088:
  588.      case 0x1f801098:
  589.      case 0x1f8010a8:
  590.      case 0x1f8010b8:
  591.      case 0x1f8010c8:
  592.      case 0x1f8010d8:
  593.      case 0x1f8010e8:
  594.           // dma_chcr
  595.           // busy‚Å‚È‚­‚È‚Á‚½‚ç readŽž‚É 0x01000000 ‚ª•Ï‚í‚é ?
  596. //        ret = 0;
  597. //        break;
  598.      case 0x1f8010f4:
  599.           // dma status
  600. //        ret = 0;
  601. //        break;
  602. #endif
  603.      default:
  604.           ret = HW32(adr-0x1f800000);
  605.           break;
  606.      }
  607. #if NOPRINTPC
  608.      printpc();
  609. #endif
  610.      PRINTF("read long %s,%08x\n",hwname(adr),(int)ret);
  611.      return ret;
  612. }
  613.  
  614. void hw_write8(UINT32 adr,UINT32 data)
  615. {
  616. #if NOPRINTPC
  617.      printpc();
  618. #endif
  619.      PRINTF("write byte %s,%02x\n",hwname(adr),(int)data);
  620.  
  621.      switch(adr){
  622.      case 0x1f801040: sio_writedata8(&Sio0,data); break;
  623.      case 0x1f801050: sio_writedata8(&Sio1,data); break;
  624.      case 0x1f801800: cd0_write(data); break;
  625.      case 0x1f801801: cd1_write(data); break;
  626.      case 0x1f801802: cd2_write(data); break;
  627.      case 0x1f801803: cd3_write(data); break;
  628.      default:
  629.           HW8(adr-0x1f800000)=data;
  630.           break;
  631.      }
  632. }
  633.  
  634. void hw_write16(UINT32 adr,UINT32 data)
  635. {
  636. #if NOPRINTPC
  637.      printpc();
  638. #endif
  639.      PRINTF("write short %s,%04x\n",hwname(adr),(int)data);
  640.  
  641.      switch(adr) {
  642.      case 0x1f801040: sio_writedata16(&Sio0,data); break;
  643.      case 0x1f801048: sio_mode_write(&Sio0,data); break;
  644.      case 0x1f80104a: sio_control_write(&Sio0,data); break;
  645.      case 0x1f80104e: sio_baud_write(&Sio0,data); break;
  646.  
  647.      case 0x1f801050: sio_writedata16(&Sio1,data); break;
  648.      case 0x1f801058: sio_mode_write(&Sio1,data); break;
  649.      case 0x1f80105a: sio_control_write(&Sio1,data); break;
  650.      case 0x1f80105e: sio_baud_write(&Sio1,data); break;
  651.  
  652.      case 0x1f801070:
  653.           /* interrupt clear? */
  654.                 HW16(0x1070) &= (data & HW16(0x1074));
  655.                 treg &= (data & HW16(0x1074));
  656.           break;
  657.         case 0x1F801104:
  658.                 HW16(0x1104) = data;
  659.                 if ((data & 0x08)==0 || !t0_target) t0_limit = UPPER;
  660.                                                else t0_limit = t0_target;
  661.                 break;
  662.         case 0x1F801108:
  663.                 HW16(0x1108) = data & 0xFFFF;
  664.                 if ((t0_mode & 0x08)==0 || !t0_target) t0_limit = UPPER;
  665.                                                   else t0_limit = t0_target;
  666.                 break;
  667.         case 0x1F801114:
  668.                 HW16(0x1114) = data;
  669.                 if ((data & 0x08)==0 || !t1_target) t1_limit = UPPER;
  670.                                                else t1_limit = t1_target;
  671.                 break;
  672.         case 0x1F801118:
  673.                 HW16(0x1118) = data & 0xFFFF;
  674.                 if ((t1_mode & 0x08)==0 || !t1_target) t1_limit = UPPER;
  675.                                                   else t1_limit = t1_target;
  676.                 break;
  677.         case 0x1F801124:
  678.                 HW16(0x1124) = data;
  679.                 if ((data & 0x08)==0 || !t2_target) t2_limit = UPPER;
  680.                                                else t2_limit = t2_target;
  681.                 break;
  682.         case 0x1F801128:
  683.                 HW16(0x1128) = data & 0xFFFF;
  684.                 if ((t2_mode & 0x08)==0 || !t2_target) t2_limit = UPPER;
  685.                                                   else t2_limit = t2_target;
  686.                 break;
  687.  
  688.      default:
  689.           if (adr>=0x1f801c00 && adr<0x1f801e00) {
  690.                SPU_Write(adr,data);
  691.                break;
  692.           }
  693.           HW16(adr-0x1f800000)=data;
  694.           break;
  695.      }
  696. }
  697.  
  698. void hw_write32(UINT32 adr,UINT32 data)
  699. {
  700. #if NOPRINTPC
  701.      printpc();
  702. #endif
  703.      PRINTF("write long %s,%08x\n",hwname(adr),(int)data);
  704.  
  705.      switch(adr) {
  706.      case 0x1f801040: sio_writedata32(&Sio0,data); break;
  707.      case 0x1f801050: sio_writedata32(&Sio1,data); break;
  708.  
  709.      case 0x1f801070:
  710.           /* ‰½‚ðƒXƒgƒA‚µ‚Ä‚à interrupt clear? */
  711.                 HW32(0x1070) &= (data & HW32(0x1074));
  712.                 treg &= (data & HW32(0x1074));
  713.           break;
  714.      case 0x1f801810: GP0_Write(data); return;
  715.      case 0x1f801814: GP1_Write(data); return;
  716.  
  717. #define   DMA_ENABLE(n)  (dma_pcr&(8<<(n*4)))
  718. #define   DMA_INTERRUPT(n)    if (dma_icr&(1<<(16+n))) dma_icr |= 0x80000000|(1<<(24+n));
  719.  
  720.      case 0x1f801088: /* MDECin */
  721.           if (DMA_ENABLE(0)) {
  722.                dma0_exec(HW32(0x1080),HW32(0x1084),data);
  723.                HW32(0x1088) = data&~0x01000000;
  724.                DMA_INTERRUPT(0);
  725.           }
  726.           break;
  727.      case 0x1f801098: /* MDECout */
  728.           if (DMA_ENABLE(1)) {
  729.                dma1_exec(HW32(0x1090),HW32(0x1094),data);
  730.                HW32(0x1098) = data&~0x01000000;
  731.                DMA_INTERRUPT(1);
  732.           }
  733.           break;
  734.      case 0x1f8010a8: /* GPU DMA */
  735.           if (DMA_ENABLE(2)) {
  736. //                        printf("GPUDMA %08x %08x %08x\n",
  737. //                                HW32(0x10a0),HW32(0x10a4),data);
  738.                GPU_DmaExec(HW32(0x10a0),HW32(0x10a4),data);
  739.                HW32(0x10A8) = data&~0x01000000;
  740.                DMA_INTERRUPT(2);
  741.           }
  742.           break;
  743.      case 0x1f8010b8: /* CDROM DMA */
  744.           if (DMA_ENABLE(3)) {
  745.                dma3_exec(HW32(0x10b0),HW32(0x10b4),data);
  746.                HW32(0x10B8) = data&~0x01000000;
  747.                DMA_INTERRUPT(3);
  748.           }
  749.           break;
  750.      case 0x1f8010c8: /* SPU DMA */
  751.           if (DMA_ENABLE(4)) {
  752.                SPU_DmaExec(HW32(0x10c0),HW32(0x10c4),data);
  753.                HW32(0x10C8) = data&~0x01000000;
  754.                DMA_INTERRUPT(4);
  755.           }
  756.           break;
  757. #if 0
  758.      case 0x1f8010d8: /* PIO DMA */
  759.           if (DMA_ENABLE(5)) {
  760.                dma5_exec(HW32(0x10D0),HW32(0x10D4),data);
  761.                HW32(0x10D8) = data&~0x01000000;
  762.                DMA_INTERRUPT(5);
  763.           }
  764.           break;
  765. #endif
  766.      case 0x1f8010e8: /* OT clear DMA */
  767.           if (DMA_ENABLE(6)) {
  768.                dma6_exec(HW32(0x10E0),HW32(0x10E4),data);
  769.                HW32(0x10E8) = data&~0x01000000;
  770.                DMA_INTERRUPT(6);
  771.           }
  772.           break;
  773.      case 0x1f8010f4:
  774.                 HW32(0x10F4) = data & 0xFFFFFF;
  775.           break;
  776.  
  777.         case 0x1F801104:
  778.                 HW32(0x1104) = data;
  779.                 if (data & 0x08) t0_limit = t0_target;
  780.                             else t0_limit = 0xFFFF;
  781.                 break;
  782.         case 0x1F801108:
  783.                 HW32(0x1108) = data & 0xFFFF;
  784.                 if (t0_mode & 0x08) t0_limit = t0_target;
  785.                                else t0_limit = 0xFFFF;
  786.                 break;
  787.         case 0x1F801114:
  788.                 HW32(0x1114) = data;
  789.                 if (data & 0x08) t1_limit = t1_target;
  790.                             else t1_limit = 0xFFFF;
  791.                 break;
  792.         case 0x1F801118:
  793.                 HW32(0x1118) = data & 0xFFFF;
  794.                 if (t1_mode & 0x08) t1_limit = t1_target;
  795.                                else t1_limit = 0xFFFF;
  796.                 break;
  797.         case 0x1F801124:
  798.                 HW32(0x1124) = data;
  799.                 if (data & 0x08) t2_limit = t2_target;
  800.                             else t2_limit = 0xFFFF;
  801.                 break;
  802.         case 0x1F801128:
  803.                 HW32(0x1128) = data & 0xFFFF;
  804.                 if (t2_mode & 0x08) t2_limit = t0_target;
  805.                                else t2_limit = 0xFFFF;
  806.                 break;
  807.  
  808.      case 0x1f801820: mdec0_write(data); break;
  809.      case 0x1f801824: mdec1_write(data); break;
  810.      default:
  811.           HW32(adr-0x1f800000)=data;
  812.           break;
  813.      }
  814. }